package com.ruoyi.system.apiService.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.apiResult.ApiRe;
import com.ruoyi.system.apiService.CouponService;
import com.ruoyi.system.component.LockComponent;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.dto.*;
import com.ruoyi.system.enums.StatusType;
import com.ruoyi.system.mapper.ZsyyCouponMapper;
import com.ruoyi.system.mapper.ZsyyParkMapper;
import com.ruoyi.system.mapper.ZsyyProductMapper;
import com.ruoyi.system.mapper.ZsyyUserCouponMapper;
import com.ruoyi.system.model.KVModel;
import org.apache.commons.math3.stat.descriptive.summary.Product;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CouponServiceImpl implements CouponService {
	@Autowired
	private ZsyyCouponMapper couponMapper;
	@Autowired
	private ZsyyUserCouponMapper userCouponMapper;
	@Autowired
	private ZsyyParkMapper parkMapper;
	@Autowired
	private ZsyyProductMapper productMapper;

	@Autowired
	private LockComponent lockComponent;

	private static final String COUPON_LOCK = "COUPON_LOCK_";

	private static final String COUPON_USER_LOCK = "COUPON_USER_LOCK_";

	private static final Logger logger = LoggerFactory.getLogger(CouponServiceImpl.class);

	@Override
	public ApiRe obtainCoupon(Long couponId, Long userId)  {
		ApiRe re = new ApiRe();
		//防止用户一瞬间提交两次表单，导致超领
		if (lockComponent.tryLock(COUPON_USER_LOCK + userId + "_" + couponId, 10)) {
			try {
				ZsyyCoupon coupon = couponMapper.selectById(couponId);
				if(coupon.getOnlyCode()==0){
					re = new ApiRe(1);
					re.setMsg("二维码已经过期！");
					return re;
				}
				if (coupon.getStatus() == StatusType.LOCK.getCode()) {
					re = new ApiRe(1);
					re.setMsg("优惠券活动已经冻结！");
					return re;
				}
				Date now = new Date();
				if (coupon.getGmtEnd() != null && coupon.getGmtEnd().getTime() < now.getTime()) {
					re = new ApiRe(1);
					re.setMsg("优惠券活动已经结束");
					return re;
				}
				if (coupon.getGmtStart() != null && coupon.getGmtStart().getTime() > now.getTime()) {
					re = new ApiRe(1);
					re.setMsg("优惠券活动还没开始");
					return re;
				}
				if (coupon.getTotal() != -1 && coupon.getSurplus() <= 0) {
					re = new ApiRe(1);
					re.setMsg("优惠券已经领完");
					return re;
				} else {
					if (coupon.getTotal() >= 0) {
						if (coupon.getSurplus() == 1) {
							if (!lockComponent.tryLock(COUPON_LOCK + couponId, 10)) {
								re = new ApiRe(1);
								re.setMsg("优惠券已经领完");
								return re;
							}
						}
					}
				}


				if (coupon.getLimitNum() != -1) {
					//校验用户是否已经领了
					Integer count = userCouponMapper.selectCount(
						new QueryWrapper<ZsyyUserCoupon>()
							.eq("user_id", userId)
							.eq("coupon_id", couponId));

					if (count >= coupon.getLimitNum()) {
						re = new ApiRe(1);
						re.setMsg("您已经领取过了");
						return re;
					}
				}

				//领取优惠券
				ZsyyUserCoupon userCoupon = new ZsyyUserCoupon();
				userCoupon.setUserId(userId);
				userCoupon.setCouponId(couponId);
				if (coupon.getDays() != null) {
					//如果是任意领取的，则从当前时间 加上 可用天数
					userCoupon.setGmtStart(now);
					userCoupon.setGmtEnd(new Date(now.getTime() + 1000l * 60 * 60 * 24 * coupon.getDays()));
				}else if (coupon.getGmtStart() != null && coupon.getGmtEnd() != null) {
					//如果优惠券是按区间领取的
					userCoupon.setGmtStart(now);
					userCoupon.setGmtEnd(coupon.getGmtEnd());
				}else {
					re = new ApiRe(1);
					re.setMsg("优惠券策略不正确");
					return re;
				}

				userCoupon.setUpdatetime(now);
				userCoupon.setCreatetime(now);

				userCouponMapper.insert(userCoupon);
				//减少优惠券剩余数量
				couponMapper.decCoupon(couponId);
				return re;
			} catch (Exception e) {
				logger.error("[领取优惠券] 异常", e);
				re = new ApiRe(1);
				return re;
			} finally {
				lockComponent.release(COUPON_USER_LOCK + userId + "_" + couponId);
			}
		} else {
			re.setCode(400);
			re.setMsg("操作过于频繁");
			return re;
		}

	}

	@Override
	public ApiRe getObtainableCoupon(Long userId)  {
		ApiRe re = new ApiRe();
		List<CouponDTO> couponS = couponMapper.getActiveCoupons();
		//活动中的优惠券Id
		List<Long> activeCouponIds = couponS.stream().map(coupon -> coupon.getId()).collect(Collectors.toList());

		if (CollectionUtils.isEmpty(activeCouponIds)) {
			re.setData(new ArrayList<CouponDTO>());
			return re;
		}

		List<KVModel<Long, Long>> userCouponsCount = couponMapper.getUserCouponsCount(userId, activeCouponIds);

		List<CouponDTO> couponDTOList = couponS.stream().map(item -> {
			item.setNowCount(0);
			for (int i = 0; i < userCouponsCount.size(); i++) {
				KVModel<Long, Long> kv = userCouponsCount.get(i);
				if (kv != null && kv.getKey().equals(item.getId())) {
					item.setNowCount(kv.getValue().intValue());
				}
			}
			return item;
		}).filter(item -> (item.getCategoryId() == null || (item.getCategoryId() != null && !StringUtils.isEmpty(item.getCategoryTitle())))).collect(Collectors.toList());
		re.setData(couponDTOList);
		return re;
	}

	@Override
	public ApiRe getUserCoupons(int status,Long userId)  {
		ApiRe re = new ApiRe();
		List<UserCouponDTO> userCoupons = userCouponMapper.getUserCoupons(status, userId);
		re.setData(userCoupons);
		return re;
	}
	// 查询用户预约时可使用的优惠券
	@Override
	public ApiRe getCouponByUidAndTid(Long id, Long tId) {
		ApiRe re = new ApiRe();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {

			QueryWrapper<ZsyyUserCoupon> wrapper = new QueryWrapper<>();
			wrapper.eq("user_id",id);
			wrapper.isNull("gmt_used");
			wrapper.lt("gmt_start",df.format(new Date()));
			wrapper.gt("gmt_end",df.format(new Date()));
			List<ZsyyUserCoupon> userCoupons = userCouponMapper.selectList(wrapper);
			List<CouponVo> couponVos = userCoupons.stream().map((item) -> {
				CouponVo couponVo = new CouponVo();
				couponVo.setUserId(item.getUserId()); //用户id
				couponVo.setCouponId(item.getCouponId());//优惠券id
				couponVo.setGmtStart(item.getGmtStart());//领取开始时间
				couponVo.setGmtEnd(item.getGmtEnd());//领取结束时间
				couponVo.setCollectionDate(item.getUpdatetime());//用户领取优惠券时间
				return couponVo;
			}).collect(Collectors.toList());

			couponVos=couponVos.stream().map((item)->{
				LambdaQueryWrapper<ZsyyCoupon> lqw = Wrappers.lambdaQuery();
				lqw.eq(ZsyyCoupon::getCourseId,tId);
				lqw.eq(ZsyyCoupon::getId,item.getCouponId());
				lqw.eq(ZsyyCoupon::getStatus,1);
				ZsyyCoupon coupon1 = couponMapper.selectOne(lqw);
				if(coupon1!=null){
					item.setTitle(coupon1.getTitle());
					item.setType(coupon1.getType());
					item.setDescription(coupon1.getDescription());
					item.setDiscount(coupon1.getDiscount());
					item.setMin(coupon1.getMin());
					item.setCourseId(coupon1.getCourseId());
					item.setDays(coupon1.getDays());
				}else{
					item=null;
				}
				return item;
			}).collect(Collectors.toList());

			couponVos=couponVos.stream().filter(item->item!=null).collect(Collectors.toList());

			couponVos=couponVos.stream().map((item)->{
				List<ZsyyProduct> products = productMapper.selectList(new QueryWrapper<ZsyyProduct>().eq("course_id", item.getCourseId()));
				if(item.getMin()>products.get(0).getPreferentialPrice()){
					item=null;
				}
//                if(item!=null){
//                    Date date = new Date();//当前系统时间
//                    String format = df.format(item.getGmtEnd()); //;使用结束时间
//                    try {
//                        item.setMaxDate(addDate(df.parse(format),item.getDays()));//最大领取时间
//                    } catch (ParseException e) {
//                        e.printStackTrace();
//                    }
//                    if(date.getTime()>item.getMaxDate().getTime()){ //当前系统时间大于最大领取时间则为已失效
//                        item=null;
//                    }
//                }
				return item;
			}).collect(Collectors.toList());
			couponVos=couponVos.stream().filter(item->item!=null).collect(Collectors.toList());
			re.setData(couponVos);
			return re;
		} catch (Exception e) {
			re.setCode(400);
			re.setMsg("系统异常,请联系管理员");
			return re;
		}
	}

	/*获取商家优惠卷*/
	@Override
	public ApiRe getUserCourse(Long userId, Integer isType, Integer status) {
		ApiRe re = new ApiRe();
		List<CouponAndUser> userCourse = couponMapper.getUserCourse(userId, isType, status);
		re.setData(userCourse);
		re.setCode(200);
		re.setMsg("成功");
		return re;
	}

	/*获取商家优惠卷通过Id*/
	@Override
	public ApiRe getInfo(Long id) {
		ApiRe re = new ApiRe();
		re.setData(couponMapper.selectById(id));
		re.setCode(200);
		re.setMsg("成功");
		return re;
	}

	@Override
	public List<CouponByParkCarDTO> getCouponByParkCar(String parkCar, Integer type, String parkCode) {

		List<CouponByParkCarDTO> couponByParkCar = couponMapper.getCouponByParkCar(parkCar,parkCode);
		List<CouponByParkCarDTO> list = new ArrayList<>();
		if(type==0){
			return couponByParkCar;
		}else if(type==1){
			for(CouponByParkCarDTO cou:couponByParkCar){
				if(cou.getGmtUsed()==null){
					CouponByParkCarDTO code = new CouponByParkCarDTO();
					code = cou;
					list.add(code);
				}
			}
			return list;
		}else {
			for(CouponByParkCarDTO cou:couponByParkCar){
				if(cou.getGmtUsed()!=null){
					CouponByParkCarDTO code = new CouponByParkCarDTO();
					code = cou;
					list.add(code);
				}
			}
			return list;
		}
	}
	@Override
	public List<CouponByParkCodeDTO> getCouponByParkCode(String parkCode,String parkName,Integer type) {
		if((parkName!=null&&parkName!="")&&(parkCode==null||parkCode=="")){
			ZsyyPark parkByParkName = parkMapper.getParkByParkName(parkName);
			parkCode = parkByParkName.getParkCode();
		}
		List<CouponByParkCodeDTO> couponByParkCode = couponMapper.getCouponByParkCode(parkCode);
		List<CouponByParkCodeDTO> list = new ArrayList<>();
		if(type==0){
			return couponByParkCode;
		}else if(type==1){
			for(CouponByParkCodeDTO cou:couponByParkCode){
				if(cou.getGmtUsed()==null){
					CouponByParkCodeDTO code = new CouponByParkCodeDTO();
					code = cou;
					list.add(code);
				}
			}
			return list;
		}else {
			for(CouponByParkCodeDTO cou:couponByParkCode){
				if(cou.getGmtUsed()!=null){
					CouponByParkCodeDTO code = new CouponByParkCodeDTO();
					code = cou;
					list.add(code);
				}
			}
			return list;
		}
	}

	//    使用优惠卷
	@Override
	public void useCoupon(Integer id) {
		couponMapper.useCoupon(id,new Date(),new Date());
	}

	@Override
	public ZsyyUserCoupon getCouponById(Integer id) {
		return userCouponMapper.selectById(id);
	}

	public static Date addDate(Date date,long day) {
		long time = date.getTime(); // 得到指定日期的毫秒数
		day = day*24*60*60*1000; // 要加上的天数转换成毫秒数
		time+=day; // 相加得到新的毫秒数
		return new Date(time); // 将毫秒数转换成日期
	}
}
